package com.zhudi.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhudi.commen.ErrorCode;
import com.zhudi.expection.BusinessException;
import com.zhudi.mapper.UserMapper;
import com.zhudi.model.entity.User;
import com.zhudi.model.request.UserLoginRequest;
import com.zhudi.model.request.UserRegisterRequest;
import com.zhudi.model.vo.UserVO;
import com.zhudi.service.UserService;
import com.zhudi.utils.SignatureUtils;
import com.zhudi.utils.UserUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import static com.zhudi.contant.UserContant.*;


/**
* @author 朱朱朱朱蒂
* @description 针对表【user(用户信息表)】的数据库操作Service实现
* @createDate 2024-02-07 23:51:09
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService {

    @Resource
    private UserMapper userMapper;


    /**
     * @param userLoginRequest 包含登录用户名和密码的请求类
     * @param request          登录成功用于保存到session中
     * @return  用户VO
     */
    @Override
    public UserVO login(UserLoginRequest userLoginRequest, HttpServletRequest request) {
        if (userLoginRequest==null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        String username = userLoginRequest.getUser_name();
        String password = userLoginRequest.getPassword();
        //账户名或者密码为空
        if (StringUtils.isAnyBlank(username,password)){
            return null;
        }

        QueryWrapper<User> userQueryWrapper=new QueryWrapper<>();
        userQueryWrapper.eq("user_name",username);
        User user = userMapper.selectOne(userQueryWrapper);
        //用户存在性检验
        if (user==null){
            return null;
        }

        //密码检验
        if (!StringUtils.equals(UserUtils.getencryptPassword(password),user.getPassword())){
            return null;

        }

        //如果都通过，说明登录成功，那么记录到session中
        request.getSession().setAttribute(USER_LOGIN_STATE,user);
        //将User信息脱敏成UserVO
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user,userVO);
        return userVO;
    }


    /**
     * @param userRegisterRequest 注册信息
     * @param request             浏览器请求
     * @return 用过户id
     */
    @Override
    public Integer register(UserRegisterRequest userRegisterRequest, HttpServletRequest request) {
        if (userRegisterRequest==null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        String username = userRegisterRequest.getUserName();
        String password = userRegisterRequest.getPassword();
        String confirmPassword = userRegisterRequest.getConfirmPassword();
        //下面是参数的合法性校验
        //账户密码空格检测
        if (StringUtils.isAnyBlank(username,password,confirmPassword)){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"账户或密码存在空格");
        }
        //两次密码相同检测
        if (!password.equals(confirmPassword)){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"两次密码不相同");
        }
        //用户名密码长度检测
        if (username.length()<USER_NAME_MIN_LENGTH){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"用户名长度过短"+USER_PASSWORD_MIN_LENGTH);
        }

        if (password.length()<USER_PASSWORD_MIN_LENGTH){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"密码长度小于"+ USER_PASSWORD_MIN_LENGTH);
        }

        //用户名重复检测
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_name",username);
        if (userMapper.selectCount(queryWrapper)>0){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"账户名重复");
        };

        //通过检测后将账户密码放入到数据库中
        User user = new User(username,UserUtils.getencryptPassword(password));
        int id = userMapper.insert(user);
        request.getSession().setAttribute(USER_LOGIN_STATE,user);;

        return id;
    }

    /**
     * 注销功能实现
     * @param request 浏览器的请求
     * @return 成功返回1
     */
    @Override
    public Integer logout(HttpServletRequest request) {
        request.getSession().removeAttribute(USER_LOGIN_STATE);

        return 1;
    }

    /**
     * 获取所有用户信息实现
     * @return 所有用户信息
     */
    @Override
    public List<UserVO> getAllUser() {
        List<User> users = userMapper.selectList(new QueryWrapper<>());
        //将User转为UserVO
        return users.stream().map(user -> {
                    UserVO userVO = new UserVO();
                    BeanUtils.copyProperties(user, userVO);
                    return userVO;
                }
        ).collect(Collectors.toList());
    }


    /**
     * 获取当户信息实现
     * @param userId 用户ID
     * @return 用户信息
     */
    @Override
    public User getUser(Long userId) {
        User user = userMapper.selectById(userId);
        return UserUtils.getSafetyUser(user);
    }

    /**
     * 获取登录的用户
     * @param request request
     * @return 如果获取不到的返回空
     */
    @Override
    public User getLoginUser(HttpServletRequest request){
        if(request==null){
            return null;
        }
       return (User) request.getSession().getAttribute(USER_LOGIN_STATE);
    }

    @Override
    public boolean update(User user, User loginUser) {
        if (user==null||loginUser==null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"请求参数为空");
        }
        //首先是判空检查
        long userId = user.getId();
        if (userId <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"目标更新用户不存在");
        }

        //接下来需要对修改的信息做合法性检查


        //用户名一般不能修改，防止绕过前端限制非法修改，后端还是要作判断
        //用户名密码长度检测
        String userName = user.getUserName();
        if(userName!=null){
            if (userName.length()<USER_NAME_MIN_LENGTH){
                throw new BusinessException(ErrorCode.PARAMS_ERROR,"用户名长度过短"+USER_PASSWORD_MIN_LENGTH);
            }
            //用户名重复检测
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user_name",userName);
            //意思是除了当前这个用户还有别的用户也是这个名字，那么就不行
            queryWrapper.ne("id",userId);
            if (userMapper.selectCount(queryWrapper)>0){
                throw new BusinessException(ErrorCode.PARAMS_ERROR,"账户名重复");
            };
        }

        //密码合法性检查
        String password = user.getPassword();
        if (password!=null){
            if (password.length()<USER_PASSWORD_MIN_LENGTH){
                throw new BusinessException(ErrorCode.PARAMS_ERROR,"密码长度小于"+ USER_PASSWORD_MIN_LENGTH);
            }
        }
        //密码要加密
        user.setPassword(UserUtils.getencryptPassword(password));

        //性别合法性检查
        //懒得改gender为Integer，强制超出合法范围的就改为合法数值
        int gender = user.getGender();
        if (gender>1){
            user.setGender(1);
        }else if (gender<0){
            user.setGender(0);
        }

        //检查手机号合法性，包括长度以及非法字符
        if (!UserUtils.isValidPhoneNumber(user.getPhone())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }


        boolean isAdmin = loginUser.getRole()==1;
        // 如果不是管理员，只允许更新当前（自己的）信息

        if(!isAdmin&&loginUser.getId()!=userId){
            throw new BusinessException(ErrorCode.NO_AUTH,"非管理员只能更新自己的信息");
        }
        // 如果是管理员，允许更新任意用户


        return userMapper.updateById(user)==1;
    }


    /**
     * @param id 要判断的用户id
     * @return 管理员为true
     */
    @Override
    public boolean isAdmin(Long id) {
        if(id<=0){
            return false;
        }
        User dbUser = userMapper.selectById(id);
        return dbUser!=null&&dbUser.getRole()==1;
    }

    @Override
    public UserVO getKeys(User loginUser) {
        if (loginUser==null||loginUser.getId()==null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"用户id为空");
        }

        Long loginUserId = loginUser.getId();
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id",loginUserId);
        queryWrapper.select("accessKey");
        queryWrapper.select("secretKey");
        User user = userMapper.selectOne(queryWrapper);
        if (user==null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"该用户不存在");
        }
        UserVO result =new UserVO();
        result.setAccesskey(user.getAccesskey());
        result.setSecretkey(user.getSecretkey());

        return result;
    }

    @Override
    public UserVO getNewKeys(User loginUser) {
        if (loginUser==null||loginUser.getId()==null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"用户id为空");
        }

        Long loginUserId = loginUser.getId();
        User user = userMapper.selectById(loginUserId);
        if (user==null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"该用户不存在");
        }

        //如果用户存在，则生成新的ak、sk，并且保存到数据库中
        Map<String, String> accessKeyAndSecertKey = SignatureUtils.getAccessKeyAndSecertKey();
        Set<Map.Entry<String, String>> entries = accessKeyAndSecertKey.entrySet();
        Map.Entry<String, String> firtsEntry = entries.iterator().next();
        String accessKey = firtsEntry.getKey();
        String secretKey = firtsEntry.getValue();
        user.setAccesskey(accessKey);
        user.setSecretkey(secretKey);

        userMapper.updateById(user);
        UserVO userVO = new UserVO();
        userVO.setAccesskey(accessKey);
        userVO.setSecretkey(secretKey);
        return userVO;
    }


}




